﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.DataAccess.SPI;
using Teld.Core.DataAccessEx.Core;
using Teld.Core.Monitor.Client;

namespace T.FAS.Runtime.DataAccess.Engine
{
    /// <summary>
    /// 内部数据访问服务
    /// </summary>
    class DatabaseImpl : IDatabase
    {
        /// <summary>
        /// 获取数据库服务
        /// </summary>
        /// <param name="sqlStatement">SQL语句</param>
        /// <returns>数据库服务</returns>
        public ITeldDatabase GetDatabase(SqlStatement sqlStatement)
        {
            var dataSourceName = sqlStatement.SqlBuildingInfo.DataSource;

            return TeldDatabaseFactory.GetDataBase(dataSourceName);
        }

        /// <summary>
        /// 获取数据库服务
        /// </summary>
        /// <param name="dataSourceName">数据源</param>
        /// <returns>数据库服务</returns>
        public ITeldDatabase GetDatabase(string dataSourceName = "")
        {
            return TeldDatabaseFactory.GetDataBase(dataSourceName);
        }

        /// <summary>
        /// 通过配置中心获取数据库服务
        /// </summary>
        /// <param name="configkey">配置key</param>
        /// <returns>数据库服务</returns>
        public ITeldDatabase GetDatabaseByConfigkey(string configkey = "")
        {
            try
            {

                return DatabaseHelper.GetDatabaseByConnectionKey(configkey);

            }
            catch (Exception e)
            {
                throw new Exception($"配置串:{configkey}生成DB访问实例失败", e);
            }
        }

        /// <summary>
        /// 在数据库事务中执行SQL语句返回影响行数
        /// </summary>
        /// <param name="sqls">SQL语句</param>        
        public void ExecuteSQLWithTransaction(SqlStatementCollection sqls)
        {
            if (sqls == null)
                throw new ArgumentNullException("DatabaseImpl.ExecuteSQLWithTransaction.sqls");

            var sqlGroups = sqls.GroupBy(i => i.SqlBuildingInfo.DataSource);

            using (var ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
                try
                {
                    foreach (var sqlGroup in sqlGroups)
                    {
                        if (sqlGroup.Count() == 0) continue;
                        var dataSourceName = sqlGroup.FirstOrDefault().SqlBuildingInfo.DataSource;

                        using (var db = GetDatabaseByConfigkey(dataSourceName))
                        {
                            foreach (var sqlstatment in sqlGroup)
                            {
                                var sqlString = sqlstatment.ToSQL();
#if DEBUG
                                System.Diagnostics.Debug.WriteLine("增删改SQL输出=========>：" + sqlString);
#endif
                                try
                                {
                                    var parameters = new List<IDbDataParameter>();
                                    parameters = CreateParameters(db, sqlstatment, parameters);
                                    LocalLogService.WriteSQL("增删改SQL输出=========>：" + sqlString, parameters?.ToArray());
                                    if (parameters == null || parameters.Count == 0)
                                    {
                                        db.ExecSqlStatement(sqlString);
                                    }
                                    else
                                    {
                                        db.ExecSqlStatement(sqlString, parameters.ToArray());
                                    }
                                }
                                catch (Exception e)
                                {
                                    MonitorError(e, sqlString);
                                    throw;
                                }
                            }
                        }
                    }

                    ts.Complete();

                }
                catch (Exception e)
                {
                    MonitorError(e, new string[sqls.Count]);
                    throw;
                }
        }

        private List<IDbDataParameter> CreateParameters(ITeldDatabase db, SqlStatement sqlStatement, List<IDbDataParameter> parameters)
        {
            if (sqlStatement is InsertSqlStatement)
                parameters = ParameterHandlerForInsert(sqlStatement, db);

            else if (sqlStatement is UpdateSqlStatement)
            {
                parameters = ParameterHandlerForUpdate(sqlStatement, db);
            }
            else if (sqlStatement is DeleteSqlStatement)
            {
                parameters = ParameterHandlerForDelete(sqlStatement, db);
            }

            return parameters;
        }

        /// <summary>
        /// 执行SQL获取数据
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>数据</returns>
        public DataSet GetData(SqlStatement sql)
        {
            if (sql == null)
                throw new ArgumentNullException("DatabaseImpl.GetData.sql");

            var sqlStrings = new string[1] { sql.ToSQL() };
            var tableNames = new string[1] { sql.SqlBuildingInfo.CurrentNode.ID };

            return GetData(sql.SqlBuildingInfo.DataSource, sqlStrings, tableNames);
        }

        /// <summary>
        /// 执行SQL获取数据
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>数据</returns>
        public List<DataTable> GetDataCollection(SqlStatementCollection sqls)
        {
            if (sqls == null)
                throw new ArgumentNullException("DatabaseImpl.GetData.sqls");

            var dataTables = new List<DataTable>();
            var sqlGroups = sqls.GroupBy(i => i.SqlBuildingInfo.DataSource);

            try
            {
                foreach (var sqlGroup in sqlGroups)
                {
                    if (sqlGroup.Count() == 0) continue;
                    var dataSourceName = sqlGroup.FirstOrDefault().SqlBuildingInfo.DataSource;

                    using (var db = GetDatabaseByConfigkey(dataSourceName))
                    {
                        foreach (var sqlstatment in sqlGroup)
                        {
                            var sqlString = sqlstatment.ToSQL();
#if DEBUG
                            System.Diagnostics.Debug.WriteLine("查询SQL输出=========>：" + sqlString);
#endif
                            try
                            {
                                var parameters = new List<IDbDataParameter>();

                                if (sqlstatment is SelectSqlStatement)
                                    parameters = ParameterHandlerForSelect(sqlstatment, db);
                                var ds = new DataSet();
                                LocalLogService.WriteSQL("查询SQL输出=========>：" + sqlString, parameters?.ToArray());
                                if (parameters == null || parameters.Count == 0)
                                {
                                    ds = db.ExecuteDataSet(sqlString);
                                }
                                else
                                {
                                    ds = db.ExecuteDataSet(sqlString, parameters.ToArray());
                                }

                                if (ds != null)
                                {
                                    int i = 0;
                                    string suffix = string.Empty;
                                    foreach (DataTable dt in ds.Tables)
                                    {
                                        if (i > 0)
                                            suffix = i.ToString();
                                        dt.TableName = sqlstatment.TableName + suffix;
                                        dataTables.Add(dt);
                                        i++;
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                MonitorError(e, sqlString);
                                throw;
                            }
                        }
                    }
                }

                return dataTables;
            }
            catch (Exception e)
            {
                MonitorError(e, new string[sqls.Count]);
                throw;
            }
        }

        /// <summary>
        /// 统一数据访问修改V1.1：
        /// 根据ModelTreeSQLBuilder获取SQL以及入参，并执行获取返回结果
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>数据</returns>
        public List<DataTable> GetDataCollectionByModelTreeSQLBuilder(ModelTreeSQLBuilder builder)
        {
            if (builder == null)
                throw new ArgumentNullException("ModelTreeSQLBuilder参数为空！");
            var dataTables = new List<DataTable>();
            try
            {
                string sqlString = builder.BuildSQL();
                var configkey = builder.Context.RootNode.DataObject.Database.DatabaseConfigs.Where(cfg => cfg.IsDefault).FirstOrDefault().ConfigKey;
                using (var db = GetDatabase())
                {
                    try
                    {
                        var parameters = new List<IDbDataParameter>();

                        if (builder.Condition.ChildCollection.Count > 0)
                            parameters = ParameterHandlerForSelect(builder.Condition, db);

                        var ds = new DataSet();
                        if (parameters == null || parameters.Count == 0)
                        {
                            ds = db.ExecuteDataSet(sqlString);
                        }
                        else
                        {
                            ds = db.ExecuteDataSet(sqlString, parameters.ToArray());
                        }

                        if (ds != null)
                        {
                            int i = 0;
                            string suffix = string.Empty;
                            foreach (DataTable dt in ds.Tables)
                            {
                                if (i > 0)
                                    suffix = i.ToString();
                                dt.TableName = "Query_" + suffix;
                                dataTables.Add(dt);
                                i++;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        MonitorError(e, sqlString);
                        throw;
                    }
                }
                return dataTables;
            }
            catch (Exception e)
            {
                MonitorError(e, new string[] { });
                throw;
            }
        }

        /// <summary>
        /// 统一数据访问修改V1.1：
        /// 根据ModelTreeSQLBuilder获取SQL以及入参，并执行获取返回结果
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>数据</returns>
        public List<DataTable> GetDataCollection(string sql, FilterConditionStatement filterConditionStatement, string dataSourceName)
        {
            if (string.IsNullOrEmpty(sql) || string.IsNullOrEmpty(dataSourceName))
                throw new ArgumentNullException("sql或dataSourceName参数不能为空！");
            var dataTables = new List<DataTable>();
            try
            {
                string sqlString = sql;
                using (var db = GetDatabaseByConfigkey(dataSourceName))
                {
                    try
                    {
                        var parameters = new List<IDbDataParameter>();

                        if (filterConditionStatement.ChildCollection.Count > 0)
                            parameters = ParameterHandlerForSelect(filterConditionStatement, db);

                        var ds = new DataSet();
                        LocalLogService.WriteSQL("分组聚合SQL输出=========>：" + sqlString, parameters?.ToArray());
                        if (parameters == null || parameters.Count == 0)
                        {
                            ds = db.ExecuteDataSet(sqlString);
                        }
                        else
                        {
                            ds = db.ExecuteDataSet(sqlString, parameters.ToArray());
                        }

                        if (ds != null)
                        {
                            int i = 0;
                            string suffix = string.Empty;
                            foreach (DataTable dt in ds.Tables)
                            {
                                if (i > 0)
                                    suffix = i.ToString();
                                dt.TableName = "Query_" + suffix;
                                dataTables.Add(dt);
                                i++;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        MonitorError(e, sqlString);
                        throw;
                    }
                }
                return dataTables;
            }
            catch (Exception e)
            {
                MonitorError(e, new string[] { });
                throw;
            }
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="dataSourceName">数据源名称</param>
        /// <param name="sqlStrings">SQL语句</param>
        /// <param name="tableNames">表名称</param>
        /// <returns>数据集</returns>
        private DataSet GetData(string dataSourceName, string[] sqlStrings, string[] tableNames)
        {
            using (var db = GetDatabaseByConfigkey(dataSourceName))
            {
                try
                {
                    DataSet dataset = db.ExecuteDataSet(sqlStrings);
                    for (int i = 0; i < tableNames.Length; i++)
                    {
                        dataset.Tables[i].TableName = tableNames[i];
                    }

                    return dataset;
                }
                catch (Exception e)
                {
                    MonitorError(e, sqlStrings);
                    throw;
                }
            }
        }

        /// <summary>
        /// 执行SQL获取数据的第一行第一列
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>数据的第一行第一列</returns>
        public object ExecuteScalar(SqlStatement sql)
        {
            var sqlStrings = sql.ToSQL();
            using (var db = GetDatabaseByConfigkey(sql.SqlBuildingInfo.DataSource))
            {
                try
                {
                    return db.ExecuteScalar(sqlStrings);
                }
                catch (Exception e)
                {
                    MonitorError(e, sqlStrings);
                    throw;
                }
            }
        }

        /// <summary>
        /// 执行SQL返回IDataReader
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <returns>IDataReader</returns>
        public IDataReader GetDataReader(SqlStatement sql)
        {
            var sqlStrings = sql.ToSQL();
            using (var db = GetDatabaseByConfigkey(sql.SqlBuildingInfo.DataSource))
            {
                try
                {
                    return db.ExecuteReader(sqlStrings);
                }
                catch (Exception e)
                {
                    MonitorError(e, sqlStrings);
                    throw;
                }
            }
        }

        /// <summary>
        /// 处理sql集合中的参数，调用底层数据访问接口，返回受影响的行数据。
        /// </summary>
        /// <param name="sqls">待处理的SQL语句集合</param>
        /// <returns>受影响的行数据</returns>
        public void ExecuteSQLs(SqlStatementCollection sqls)
        {
            if (sqls == null)
                throw new ArgumentNullException("DatabaseImpl.ExecuteSQLs.sqls");
            if (sqls.Count == 0)
                return;

            foreach (var sqlstatment in sqls)
            {
                using (var db = GetDatabaseByConfigkey(sqlstatment.SqlBuildingInfo.DataSource))
                {
                    var sqlString = sqlstatment.ToSQL();
                    try
                    {
                        var parameters = new List<IDbDataParameter>();

                        if (sqlstatment is InsertSqlStatement)
                            parameters = ParameterHandlerForInsert(sqlstatment, db);

                        else if (sqlstatment is UpdateSqlStatement)
                        {
                            parameters = ParameterHandlerForUpdate(sqlstatment, db);
                        }

                        if (parameters == null || parameters.Count == 0)
                        {
                            db.ExecSqlStatement(sqlString);
                        }
                        else
                        {
                            db.ExecSqlStatement(sqlString, parameters);
                        }
                    }
                    catch (Exception e)
                    {
                        MonitorError(e, sqlString);
                        throw;
                    }
                }
            }
        }

        /// <summary>
        /// 对Update类SQL语句进行参数处理
        /// </summary>
        /// <param name="sqlStatement">待处理的SQL语句</param>
        /// <param name="db">数据访问对象</param>
        /// <returns>处理后的参数数组</returns>
        private List<IDbDataParameter> ParameterHandlerForUpdate(SqlStatement sqlStatement, ITeldDatabase db)
        {
            var updateSql = sqlStatement as UpdateSqlStatement;
            var parameters = new List<IDbDataParameter>(updateSql.UpdateFields.ChildCollection.Count);

            for (int parameterIndex = 0; parameterIndex < updateSql.UpdateFields.ChildCollection.Count; parameterIndex++)
            {
                UpdateField updateField = updateSql.UpdateFields.ChildCollection[parameterIndex] as UpdateField;
                if (updateField == null)
                    throw new Exception("ParameterHandlerForUpdate.updateField, parameterIndex:" + parameterIndex);

                FieldValue feildValue = updateSql.UpdateValues.ChildCollection[parameterIndex] as FieldValue;
                if (feildValue == null)
                    throw new Exception("ParameterHandlerForUpdate.feildValue, parameterIndex:" + parameterIndex);

                parameters.Add(ParameterHandler(db, feildValue, updateField, DataAccessOpType.U));
            }
            //****统一数据访问服务v1.2，update sql参数增加主键条件解析。
            if(updateSql.UpdateCondition.ChildCollection.Count > 0)
            {
                foreach (var filterCondition in updateSql.UpdateCondition.ChildCollection)
                {
                    if (filterCondition is SqlPrimaryKey)
                    {
                        foreach (var keyField in filterCondition.ChildCollection)
                        {
                            if (!(keyField is SqlPrimaryKeyField pkField))
                                continue; //非主键条件不做处理

                            parameters.Add(ParameterHandler(db, pkField.Value, pkField, DataAccessOpType.U));
                        }
                    }
                }
            }

            return parameters;
        }

        /// <summary>
        /// 对Select类SQL语句进行参数处理
        /// </summary>
        /// <param name="sqlStatement">待处理的SQL语句</param>
        /// <param name="db">数据访问对象</param>
        /// <returns>处理后的参数数组</returns>
        private List<IDbDataParameter> ParameterHandlerForSelect(SqlStatement sqlStatement, ITeldDatabase db)
        {
            var selectSql = sqlStatement as SelectSqlStatement;
            List<IDbDataParameter> parameters = null;
            if (selectSql.FilterCondition != null)
                parameters = ParameterHandlerForSelectFunc(selectSql.FilterCondition, db);
            return parameters;
        }

        /// <summary>
        /// 对Select类SQL语句进行参数处理
        /// </summary>
        /// <param name="sqlStatement">待处理的SQL语句</param>
        /// <param name="db">数据访问对象</param>
        /// <returns>处理后的参数数组</returns>
        private List<IDbDataParameter> ParameterHandlerForSelectFunc(FilterConditionStatement condition, ITeldDatabase db)
        {
            var parameters = new List<IDbDataParameter>();

            if (condition?.ChildCollection == null || condition.ChildCollection.Count == 0)
                return parameters;
            foreach (var child in condition.ChildCollection)
            {
                if (child is SqlPrimaryKey primaryKey)
                {
                    foreach (var keyField in primaryKey.ChildCollection)
                    {
                        SqlPrimaryKeyField pkField = keyField as SqlPrimaryKeyField;
                        if (pkField == null)
                            throw new Exception("ParameterHandlerForSelectFunc.pkField, keyField:" + keyField.ToSQL());
                        parameters.Add(ParameterHandler(db, pkField.Value, pkField, DataAccessOpType.Q));
                    }
                }
                else if(child is ConditionStatement conditionStatement)
                {
                    parameters.Add(ParameterHandler(db, conditionStatement.ConditionFieldValue, conditionStatement.ConditionField, DataAccessOpType.Q, conditionStatement.ConditionFieldValue.ConditionFieldName));
                }
                else if(child is FilterConditionStatement filterConditionStatement)
                {
                    parameters.AddRange(ParameterHandlerForSelectFunc(filterConditionStatement, db));
                }
            }
            return parameters;
        }

        /// <summary>
        /// 对Select类SQL语句进行参数处理
        /// </summary>
        /// <param name="sqlStatementCondition">待处理的条件元素</param>
        /// <param name="db">数据访问对象</param>
        /// <returns>处理后的参数数组</returns>
        private List<IDbDataParameter> ParameterHandlerForSelect(FilterConditionStatement sqlStatementCondition, ITeldDatabase db)
        {
            List<IDbDataParameter> parameters = null;
            if (sqlStatementCondition != null)
                parameters = ParameterHandlerForSelectFunc(sqlStatementCondition, db);
            return parameters;
        }

        ///// <summary>
        ///// 对Select类SQL语句进行参数处理
        ///// </summary>
        ///// <param name="sqlStatementCondition">待处理的条件元素</param>
        ///// <param name="db">数据访问对象</param>
        ///// <returns>处理后的参数数组</returns>
        //private List<IDbDataParameter> ParameterHandlerForSelect(FilterConditionStatement sqlStatementCondition, ITeldDatabase db)
        //{
        //    var parameters = new List<IDbDataParameter>(sqlStatementCondition.ChildCollection.Count);

        //    foreach (var item in sqlStatementCondition.ChildCollection)
        //    {
        //        var conditionStatetment = item as ConditionStatement;
        //        parameters.Add(ParameterHandler(db, conditionStatetment.ConditionFieldValue, conditionStatetment.ConditionField, DataAccessOpType.Q, conditionStatetment.ConditionFieldValue.ConditionFieldName));
        //    }

        //    return parameters;
        //}

        /// <summary>
        /// 对Select类SQL语句进行参数处理
        /// </summary>
        /// <param name="sqlStatement">待处理的SQL语句</param>
        /// <param name="db">数据访问对象</param>
        /// <returns>处理后的参数数组</returns>
        private List<IDbDataParameter> ParameterHandlerForDelete(SqlStatement sqlStatement, ITeldDatabase db)
        {
            var deleteSql = sqlStatement as DeleteSqlStatement;
            var parameters = new List<IDbDataParameter>();

            if (deleteSql.SubQuerySql != null)
            {
                for (int parameterIndex = 0; parameterIndex < deleteSql.SubQuerySql.Condition.ChildCollection.Count; parameterIndex++)
                {
                    var filterCondition = deleteSql.SubQuerySql.Condition.ChildCollection[parameterIndex];
                    if (filterCondition is SqlPrimaryKey)
                    {
                        foreach (var keyField in filterCondition.ChildCollection)
                        {
                            SqlPrimaryKeyField pkField = keyField as SqlPrimaryKeyField;
                            if (pkField == null)
                                throw new Exception("ParameterHandlerForDelete.PkField, parameterIndex:" + parameterIndex);

                            parameters.Add(ParameterHandler(db, pkField.Value, pkField, DataAccessOpType.D));
                        }
                    }
                }
            }
            else
            {
                for (int parameterIndex = 0; parameterIndex < deleteSql.Conditions.ChildCollection.Count; parameterIndex++)
                {
                    var filterCondition = deleteSql.Conditions.ChildCollection[parameterIndex];
                    if (filterCondition is SqlPrimaryKey)
                    {
                        foreach (var keyField in filterCondition.ChildCollection)
                        {
                            SqlPrimaryKeyField pkField = keyField as SqlPrimaryKeyField;
                            if (pkField == null)
                                throw new Exception("ParameterHandlerForDelete.PkField, parameterIndex:" + parameterIndex);

                            parameters.Add(ParameterHandler(db, pkField.Value, pkField, DataAccessOpType.D));
                        }
                    }
                }
            }

            return parameters;
        }

        /// <summary>
        /// 对Insert类SQL语句进行参数处理
        /// </summary>
        /// <param name="sqlStatement">待处理的SQL语句</param>
        /// <param name="db">数据访问对象</param>
        /// <returns>处理后的参数数组</returns>
        private List<IDbDataParameter> ParameterHandlerForInsert(SqlStatement sqlStatement, ITeldDatabase db)
        {
            var insertSql = sqlStatement as InsertSqlStatement;
            var parameters = new List<IDbDataParameter>(insertSql.InsertFields.ChildCollection.Count);

            for (int parameterIndex = 0; parameterIndex < insertSql.InsertFields.ChildCollection.Count; parameterIndex++)
            {
                InsertField insertField = insertSql.InsertFields.ChildCollection[parameterIndex] as InsertField;
                if (insertField == null)
                    throw new Exception("ParameterHandlerForInsert.insertField, parameterIndex:" + parameterIndex);

                InsertValue insertValue = insertSql.InsertValues.ChildCollection[parameterIndex] as InsertValue;
                if (insertValue == null)
                    throw new Exception("ParameterHandlerForInsert.insertValue, parameterIndex:" + parameterIndex);

                parameters.Add(ParameterHandler(db, insertValue, insertField, DataAccessOpType.I));
            }

            return parameters;
        }

        /// <summary>
        /// 处理特殊数据类型参数
        /// </summary>
        /// <param name="db">数据访问对象</param>
        /// <param name="parameters">参数列表</param>
        /// <param name="fieldValue">字段值</param>
        /// <param name="field">待处理字段</param>
        private IDbDataParameter ParameterHandler(ITeldDatabase db, FieldValue fieldValue, Field field, DataAccessOpType type, string fieldName = "")
        {
            if (string.IsNullOrEmpty(fieldName))
                fieldName = field.FieldName;
            if (type == DataAccessOpType.Q) //查询语句的SQL参数占位符需要加入表名前缀
            {

                if (!string.IsNullOrEmpty(field.Table?.TablePrefix))
                {
                    if (field is SqlPrimaryKeyField)
                    {
                        fieldName = field.FieldName;
                    }
                    else if ((field is ConditionField) && (fieldValue is ConditionFieldValue))
                    {
                        fieldName = field.Table.TablePrefix + "_" + (fieldValue as ConditionFieldValue).ConditionFieldName;
                    }
                    else
                    {
                        throw new Exception("生成查询SQL的Parameter时参数类型不正确");
                    }
                }
                else
                {
                    throw new Exception(field.FieldName + "字段没有表名前缀");
                }
            }

            IDbDataParameter parameter;
            switch ((ElementDataType)fieldValue.DataType)
            {
                case ElementDataType.DateTime:
                case ElementDataType.Date:
                    parameter = db.MakeInParam(fieldName, TeldDbDataType.DateTime, fieldValue.Value);
                    break;
                case ElementDataType.Binary:
                    {
                        byte[] byteArray = fieldValue.Value as Byte[];
                        parameter = db.MakeInParam(fieldName, TeldDbDataType.Blob, byteArray);
                        break;
                    }
                case ElementDataType.Boolean:
                case ElementDataType.Integer:
                    parameter = db.MakeInParam(fieldName, TeldDbDataType.Int, fieldValue.Value);
                    break;
                case ElementDataType.Decimal:
                    parameter = db.MakeInParam(fieldName, TeldDbDataType.Decimal, fieldValue.Value);
                    break;
                case ElementDataType.String:
                    parameter = db.MakeInParam(fieldName, TeldDbDataType.VarChar, fieldValue.Value);
                    break;
                case ElementDataType.Text:
                    parameter = db.MakeInParam(fieldName, TeldDbDataType.Clob, fieldValue.Value);
                    break;
                default:
                    throw new NotSupportedException(((ElementDataType)fieldValue.DataType).ToString());
            }

            return parameter;
        }

        private void MonitorError(Exception e, params string[] sqls)
        {
            if (sqls == null)
                sqls = new string[0];

            var context = new Dictionary<string, string>()
            {
                {"Error", e.ToString()},
                {"sqls",string.Join(",", sqls)}
            };

            MonitorClient.Send("DataAccessSqlError", 1, null, context);
        }
    }
}
